﻿using gt.rediscache.core.Entry;
using gt.rediscache.core.Utility;
using StackExchange.Redis;
using System.Threading.Tasks;

namespace gt.rediscache.core.Clients
{
    public partial class RedisClient
    {
        /// <summary>
        /// index 获取value
        /// </summary>
        public string ListGet(string key, int index, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListGetMessage(key, index);
            return Execute(RedisCommand.ListGetByIndex, message, flags).RedisValueResult;
        }
        /// <summary>
        /// 在另一个value右边，插入list value,
        //   the length of the list after the insert operation, or -1 when the value pivot
        //   was not found.
        /// </summary>
        public long ListInsertAfter(string key, string pivot, string insertValue, CommandFlags flags = CommandFlags.None)
        {
            //to do param check
            var message = new ListInsertAfterMessage(key, pivot, insertValue);
            return Execute(RedisCommand.ListInsertAfter, message, flags).LongResult;
        }
        /// <summary>
        /// 在另一个value左边，插入list value,
        //   the length of the list after the insert operation, or -1 when the value pivot
        //   was not found.
        /// </summary>
        public long ListInsertBefore(string key, string pivot, string insertValue, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListInsertBeforeMessage(key, pivot, insertValue);
            return Execute(RedisCommand.ListInsertBefore, message, flags).LongResult;
        }
        /// <summary>
        /// 返回左边头一个key-value并删除
        /// </summary>
        public string ListLeftPop(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListLeftPopMessage(key);
            return Execute(RedisCommand.ListLeftPop, message, flags).RedisValueResult;
        }
        /// <summary>
        /// 从左边插入一个key-value
        /// 返回long length
        /// </summary>
        public long ListLeftPush(string key, string value, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListLeftPushMessage(key, value, when);
            return Execute(RedisCommand.ListLeftPush, message, flags).LongResult;
        }
        /// <summary>
        /// list长度
        /// </summary>
        public long ListLength(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListLengthMessage(key);
            return Execute(RedisCommand.ListLength, message, flags).LongResult;
        }
        /// <summary>
        /// 获取某一段list key-value
        /// 从 startIndex 到 endIndex(包括endIndex)
        /// </summary>
        public string[] ListRange(string key, long startIndex, long endIndex, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRangeMessage(key, startIndex, endIndex);
            var result = Execute(RedisCommand.ListRange, message, flags).RedisValueArrayResult;
            return RedisValueConverter.Convert(result);
        }
        /// <summary>
        /// 返回右边头一个key-value并删除
        /// </summary>
        public string ListRightPop(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRightPopMessage(key);
            return Execute(RedisCommand.ListRightPop, message, flags).RedisValueResult;
        }
        /// <summary>
        /// 从右边插入一个key-value
        /// 返回long length
        /// </summary>
        public long ListRightPush(string key, string value, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRightPushMessage(key, value, when);
            return Execute(RedisCommand.ListRightPush, message, flags).LongResult;
        }
        /// <summary>
        /// 按序号插入value,序号不能超过队列长度
        /// </summary>
        public void ListSetByIndex(string key, long index, string value, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListSetByIndexMessage(key, value, index);
            Execute(RedisCommand.ListSetByIndex, message, flags);
        }
        /// <summary>
        /// 保留队列一段数据
        /// </summary>
        public void ListTrim(string key, long start, long stop, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListTrimMessage(key, start, stop);
            Execute(RedisCommand.ListTrim, message, flags);
        }
        public long ListRemove(string key, string value, long count = 0, StackExchange.Redis.CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRemoveMessage(key, value, count);
            return Execute(RedisCommand.ListRemove, message, flags).LongResult;
        }

        #region Async


        /// <summary>
        /// index 获取value
        /// </summary>
        public async Task<string> ListGetAsync(string key, int index, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListGetMessage(key, index);
            return await ExecuteAsync(RedisCommand.ListGetByIndex, message, flags).ContinueWith(t =>
            {
                return t.Result.RedisValueResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 在另一个value右边，插入list value,
        /// </summary>
        public async Task<long> ListInsertAfterAsync(string key, string pivot, string insertValue, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListInsertAfterMessage(key, pivot, insertValue);
            return await ExecuteAsync(RedisCommand.ListInsertAfter, message, flags).ContinueWith(t =>
            {
                return t.Result.LongResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 在另一个value左边，插入list value,
        /// </summary>
        public async Task<long> ListInsertBeforeAsync(string key, string pivot, string insertValue, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListInsertBeforeMessage(key, pivot, insertValue);
            return await ExecuteAsync(RedisCommand.ListInsertBefore, message, flags).ContinueWith(t =>
            {
                return t.Result.LongResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 返回左边头一个key-value并删除
        /// </summary>
        public async Task<string> ListLeftPopAsync(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListLeftPopMessage(key);
            return await ExecuteAsync(RedisCommand.ListLeftPop, message, flags).ContinueWith(t =>
            {
                return t.Result.RedisValueResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 从左边插入一个key-value
        /// 返回long length
        /// </summary>
        public async Task<long> ListLeftPushAsync(string key, string value, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListLeftPushMessage(key, value, when);
            return await ExecuteAsync(RedisCommand.ListLeftPush, message, flags).ContinueWith(t =>
            {
                return t.Result.LongResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// list长度
        /// </summary>
        public async Task<long> ListLengthAsync(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListLengthMessage(key);
            return await ExecuteAsync(RedisCommand.ListLength, message, flags).ContinueWith(t =>
            {
                return t.Result.LongResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 获取某一段list key-value
        /// 从 startIndex 到 endIndexAsync(包括endIndex)
        /// </summary>
        public async Task<string[]> ListRangeAsync(string key, long startIndex, long endIndex, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRangeMessage(key, startIndex, endIndex);
            return await ExecuteAsync(RedisCommand.ListRange, message, flags).ContinueWith((task) =>
            {
                return RedisValueConverter.Convert(task.Result.RedisValueArrayResult);
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 返回右边头一个key-value并删除
        /// </summary>
        public async Task<string> ListRightPopAsync(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRightPopMessage(key);
            return await ExecuteAsync(RedisCommand.ListRightPop, message, flags).ContinueWith(t =>
            {
                return t.Result.RedisValueResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 从右边插入一个key-value
        /// 返回long length
        /// </summary>
        public async Task<long> ListRightPushAsync(string key, string value, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRightPushMessage(key, value, when);
            return await ExecuteAsync(RedisCommand.ListRightPush, message, flags).ContinueWith(t =>
            {
                return t.Result.LongResult;
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// 按序号插入value,序号不能超过队列长度
        /// </summary>
        public async Task ListSetByIndexAsync(string key, long index, string value, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListSetByIndexMessage(key, value, index);
            await ExecuteAsync(RedisCommand.ListSetByIndex, message, flags).ConfigureAwait(false);
        }
        /// <summary>
        /// 保留队列一段数据
        /// </summary>
        public async Task ListTrimAsync(string key, long start, long stop, CommandFlags flags = CommandFlags.None)
        {
            var message = new ListTrimMessage(key, start, stop);
            await ExecuteAsync(RedisCommand.ListTrim, message, flags).ConfigureAwait(false);
        }
        public async Task<long> ListRemoveAsync(string key, string value, long count = 0, StackExchange.Redis.CommandFlags flags = CommandFlags.None)
        {
            var message = new ListRemoveMessage(key, value, count);
            return await ExecuteAsync(RedisCommand.ListRemove, message, flags).ContinueWith(t =>
            {
                return t.Result.LongResult;
            }).ConfigureAwait(false);
        }

        #endregion
    }
}
